package base.thread;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;

public class NotAtomicDemo {


    private static int n;
    private static AtomicInteger atomicInteger;
    private static AtomicStampedReference atomicStampedReference;

    public static void main(String[] args) throws InterruptedException {
        atomicAdd();
    }

    /**
     * 非原子性加法
     * @throws InterruptedException
     */
    public static void notAtomicAdd() throws InterruptedException {
        int j = 0;
        while (j < 100) {
            n = 0;
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i=0;i<10000;i++) n++;
                }
            });

            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i=0;i<10000;i++) n++;
                }
            });

            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            j++;
            System.out.println("n  = "+n);

        }
    }


     public static void atomicAdd() throws InterruptedException {
        int j = 0;
        while (j < 100) {
            atomicInteger=new AtomicInteger(0);
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i=0;i<10000;i++) atomicInteger.getAndIncrement();
                }
            });

            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i=0;i<10000;i++)
                        atomicInteger.getAndIncrement();//原子性++
                }
            });

            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            j++;
            System.out.println("atomicInteger  = "+atomicInteger);

        }
    }

  public static void atomicStampeAdd() throws InterruptedException {
        int j = 0;
        while (j < 100) {
            atomicStampedReference=new AtomicStampedReference(0,0);// 初始值，初始时间值
            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {

                    for (int i=0;i<10000;i++) {

                        int stamp;
                        Integer reference;
                        do {
                            stamp=atomicStampedReference.getStamp();
                            reference= (Integer) atomicStampedReference.getReference();
                        }while (!atomicStampedReference.compareAndSet(reference,reference+1,stamp,stamp+1));


                    }

                }
            });

            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int i=0;i<10000;i++){

                        int stamp;
                        Integer reference;
                        do {
                            stamp=atomicStampedReference.getStamp();
                            reference= (Integer) atomicStampedReference.getReference();
                        }while (!atomicStampedReference.compareAndSet(reference,reference+1,stamp,stamp+1));


                    }
                }
            });

            thread1.start();
            thread2.start();
            thread1.join();
            thread2.join();
            j++;
            System.out.println("atomicInteger  = "+atomicInteger);

        }
    }






}
//n  = 17698
//n  = 20000
//n  = 20000
//n  = 19252
//n  = 20000
//n  = 20000
//n  = 20000